#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@ author:konnlee
@ time  :2020/6/1 12:46
@ School:BESTI
"""
import os
import sys
import requests
import my_ftp_server as ftp
from bs4 import BeautifulSoup
from PyQt5.QtWidgets import QPushButton, QApplication, QToolTip, QWidget, QMessageBox, QMainWindow
from PyQt5.QtWidgets import QTextEdit, QFileDialog, QFileDialog, QLabel
from PyQt5.QtGui import QIcon, QFont, QPixmap

# 全局变量
string = ""
size_up = 0
size_now = 0
list_show_up = []
list_show_now = []
info_up = []
info_now = []
up_index = 0
now_index = 0


def now_up_playing_get():
    global size_up, size_now, list_show_now, list_show_up
    """
    爬取豆瓣首页当前即将上映或正在上映的电影信息
    :return: Two list,The first one is the info of the movies coming soon,
    The second one is the info of the movies playing
    """
    url = 'https://movie.douban.com/cinema/nowplaying/beijing/'
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/83.0.4103.61 Safari/537.36'
    }
    re = requests.get(url, headers=headers)
    soup = BeautifulSoup(re.text, 'html.parser')
    movies = soup.findAll('li', {'class': 'list-item'})
    list_now = []
    list_up = []
    for movie in movies:
        dic = {}
        status = movie['data-category']          # 上映状态
        dic.setdefault('status', status)
        if status == 'upcoming':
            name = movie['data-title']          # 电影名字
            dic.setdefault('name', name)
            string_info = "电影名字：" + name
            string_info += "\n\n上映状态：即将上映，敬请期待！"
            movie_id = movie['id']              # 电影id，方便查看具体信息
            dic.setdefault('movie_id', movie_id)
            region = movie['data-region']       # 电影产地
            dic.setdefault('region', region)
            string_info += "\n\n电影产地：" + region
            director = movie["data-director"]   # 导演
            dic.setdefault('director', director)
            string_info += "\n\n导演：" + director
            actor = movie['data-actors']        # 主演
            dic.setdefault('actor', actor)
            string_info += "\n\n电影主演：" + actor
            time = movie['data-duration']       # 时长
            dic.setdefault('time', time)
            string_info += "\n\n电影时长：" + time
            more_info = movie.find('a', {'target': '_blank'})
            img = more_info.find('img')['src']  # 海报地址
            dic.setdefault('img', img)
            detail = more_info['href']          # 详细信息界面
            dic.setdefault('detail', detail)
            list_up.append(dic)
            info_up.append(string_info)
        else:
            name = movie['data-title']          # 电影名字
            dic.setdefault('name', name)
            string_info = "电影名字：" + name
            string_info += "\n\n上映状态：正在上映！"
            movie_id = movie['id']              # 电影id，方便查看具体信息
            dic.setdefault('movie_id', movie_id)
            region = movie['data-region']       # 电影产地
            dic.setdefault('region', region)
            string_info += "\n\n电影产地：" + region
            director = movie['data-director']   # 导演
            dic.setdefault('director', director)
            string_info += "\n\n导演：" + director
            actor = movie['data-actors']        # 主演
            dic.setdefault('actor', actor)
            string_info += "\n\n电影主演：" + actor
            time = movie['data-duration']       # 时长
            dic.setdefault('time', time)
            string_info += "\n\n电影时长：" + time
            vote_count = movie['data-votecount']  # 评分人数
            dic.setdefault('vote_count', vote_count)
            string_info += "\n\n豆瓣评分人数：" + vote_count
            more_info = movie.find('a', {'target': '_blank'})
            img = more_info.find('img')['src']  # 海报地址
            dic.setdefault('img', img)
            detail = more_info['href']          # 详细信息界面
            dic.setdefault('detail', detail)
            if movie.find('span', {'class': 'subject-rate'}) is not None:
                star = movie.find('span', {'class': 'subject-rate'}).text    # 获取评分
                dic.setdefault('star', star)
                string_info += "\n\n豆瓣评分：" + star
            list_now.append(dic)
            info_now.append(string_info)
    list_show_now = list_now
    list_show_up = list_up
    size_up, size_now = len(list_up), len(list_now)
    return list_up, list_now


def print_movie_list(a, b):
    """
    To print a menu which spider get.
    :param a:Movies playing now's info's list.
    :param b:Movies playing soon's info's list.
    :return: None
    """
    global string
    string += '\n'
    string += "以下电影即将上映！".center(60, '*')
    string += '\n'
    for i in a:
        string = string + str(a.index(i) + 1) + i['name'].center(60, ' ')
        string += '\n'
    string += '\n'
    string += str("以下电影正在热映！".center(60, '*'))
    string += '\n'
    for i in b:
        string = string + str(b.index(i) + 1) + i['name'].center(60, ' ')
        string += '\n'


class Frame(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_MainWin()
        self.setFixedSize(self.width(), self.height())
        self.init_buttons()

    def init_MainWin(self):
        self.setGeometry(100, 100, 1600, 900)
        self.setWindowTitle("豆瓣爬虫")
        self.setToolTip("这是一个由<h5>konnlee</h5>编写的程序")
        self.setWindowIcon(QIcon("无标题.jpg"))
        self.statusBar().showMessage('准备就绪！')

    def init_buttons(self):
        # 退出按钮
        ex_button = QPushButton("按下退出程序", self)
        ex_button.setToolTip("按下此按钮退出程序")
        ex_button.sizeHint()
        ex_button.move(900, 800)
        ex_button.clicked.connect(self.close)

        # 开始爬取按钮
        get_button = QPushButton("按下开始爬取", self)
        get_button.setToolTip("按下此按钮开始从豆瓣爬取即将上映和正在上映的电影")
        get_button.sizeHint()
        get_button.move(700, 800)
        get_button.clicked.connect(self.start_get)

        # 查看详细信息按钮
        detail_look = QPushButton("查看详细信息", self)
        detail_look.setToolTip("按下此按钮查看更多信息")
        detail_look.sizeHint()
        detail_look.move(1050, 100)
        detail_look.clicked.connect(self.detail)

        # 写入文件按钮
        write_file = QPushButton("结果写入文件", self)
        write_file.setToolTip("按下此按钮将爬取到的结果写入文件")
        write_file.sizeHint()
        write_file.move(1200, 100)
        write_file.clicked.connect(self.openfile)

        # 打开文件
        open_file = QPushButton("打开文件", self)
        open_file.setToolTip("按下此按钮打开文件")
        open_file.sizeHint()
        open_file.move(1350, 100)
        open_file.clicked.connect(self.readfile)

    def start_get(self):
        """
        开始按钮绑定的自定义事件，启动爬虫爬取电影信息
        :return:None
        """
        list_up, list_now = now_up_playing_get()
        print_movie_list(list_up, list_now)
        self.init_text(string)
        QMessageBox.information(self, "提示", "院线电影信息爬取完毕！")
        self.statusBar().showMessage("爬取完毕！")

    def init_text(self, string=' '):
        """
        这个函数更新在文本框中显示的内容，同时限定此文本框为只读模式，不允许用户修改查询到的地方
        :param string: 想在文本框中显示的内容
        :return: None
        """
        mo_text = QTextEdit(self)
        mo_text.setFont(QFont("fangsong", 12))
        mo_text.clear()
        mo_text.setPlainText(string)
        mo_text.setToolTip("这个文本框显示了爬虫爬取的即将上映或正在上映的电影信息")
        mo_text.setGeometry(100, 100, 800, 450)
        mo_text.setReadOnly(True)
        mo_text.show()

        summary = QTextEdit(self)
        summary.setFont(QFont("Microsoft YaHei", 11))
        summary.setText("统计信息:\t\t即将上映：" + str(size_up) + "\t\t\t正在上映：" + str(size_now))
        summary.setGeometry(100, 550, 800, 35)
        summary.setReadOnly(True)
        summary.show()

    def detail(self):
        """
        查看详细信息的函数，询问用户要查看的信息的种类
        :return: None
        """
        choose = QLabel(self)
        choose.setGeometry(1050, 150, 100, 30)
        choose.setText("查看电影信息？：")
        choose.show()
        up = QPushButton("即将上映", self)
        up.sizeHint()
        up.move(1170, 150)
        up.show()
        up.clicked.connect(self.show_detail_up)
        now = QPushButton("正在上映", self)
        now.sizeHint()
        now.move(1270, 150)
        now.show()
        now.clicked.connect(self.show_detail_now)

    def show_detail_up(self):
        """
        展示即将上映的电影的详细信息
        :return: None
        """
        detail_text = QTextEdit(self)
        detail_text.setGeometry(950, 200, 600, 500)
        detail_text.setToolTip("这个文本框显示了即将上映电影的详细信息")
        detail_text.setReadOnly(True)
        detail_text.show()
        try:
            detail_text.setText(info_up[up_index])
        except:
            QMessageBox.information(self, "警告", "请先点击按钮爬取信息再查看具体信息")
        last = QPushButton("上一个", self)
        last.sizeHint()
        last.move(1100, 700)
        last.show()
        last.clicked.connect(self.last)
        next1 = QPushButton("下一个", self)
        next1.sizeHint()
        next1.move(1250, 700)
        next1.show()
        next1.clicked.connect(self.next)
        look_picture = QPushButton("查看海报", self)
        look_picture.sizeHint()
        look_picture.show()
        look_picture.move(950, 700)
        look_picture.clicked.connect(self.show_picture_up)
        ftp_button = QPushButton("上传服务器", self)
        ftp_button.sizeHint()
        ftp_button.move(1400, 700)
        ftp_button.show()
        ftp_button.clicked.connect(self.ftp_push)

    def next(self):
        """
        改变查看索引值
        :return: None
        """
        global up_index
        if up_index < len(list_show_up) - 1:
            up_index += 1
        else:
            QMessageBox.information(self, "提示", "当前已经是最后一个结果！")
            up_index = 5

    def last(self):
        """
        改变查看索引值
        :return: None
        """
        global up_index
        if up_index > 0:
            up_index -= 1
        else:
            QMessageBox.information(self, "提示", "当前已经是第一个结果！")
            up_index = 0

    def show_picture_up(self):
        """
        展示即将上映的电影的海报
        :return: None
        """
        headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/83.0.4103.97 Safari/537.36 Edg/83.0.478.45 '
        }
        try:
            res = requests.get(list_show_up[up_index]['img'], headers=headers)
            root = "F://python全栈//python程序设计大实验//"
            path = root + '1.jpg'
            if not os.path.exists(root):
                os.mkdir(root)
            with open(path, 'wb') as f:
                f.write(res.content)
                f.close()
        except:
            QMessageBox.information(self, "提示", "海报资源请求错误")
        pix = QPixmap('1.jpg')
        picture_lab = QLabel(self)
        picture_lab.setGeometry(950, 400, 600, 300)
        picture_lab.setPixmap(pix)
        picture_lab.setStyleSheet("border: 2px solid red")
        picture_lab.setScaledContents(True)
        picture_lab.show()

    def show_detail_now(self):
        """
        展示正在上映的电影的详细信息
        :return: None
        """
        detail_text = QTextEdit(self)
        detail_text.setGeometry(950, 200, 600, 500)
        detail_text.setToolTip("这个文本框显示了正在上映电影的详细信息")
        detail_text.setReadOnly(True)
        detail_text.show()
        try:
            detail_text.setText(info_now[now_index])
        except:
            QMessageBox.information(self, "警告", "请先点击按钮爬取信息再查看具体信息")
        last2 = QPushButton("上一个", self)
        last2.sizeHint()
        last2.move(1150, 700)
        last2.show()
        last2.clicked.connect(self.last2)
        next2 = QPushButton("下一个", self)
        next2.sizeHint()
        next2.move(1350, 700)
        next2.show()
        next2.clicked.connect(self.next2)
        look_picture2 = QPushButton("查看海报", self)
        look_picture2.sizeHint()
        look_picture2.show()
        look_picture2.move(950, 700)
        look_picture2.clicked.connect(self.show_picture_now)
        ftp_button = QPushButton("上传服务器", self)
        ftp_button.sizeHint()
        ftp_button.move(1400, 700)
        ftp_button.show()
        ftp_button.clicked.connect(self.ftp_push)

    def ftp_push(self):
        """
        调用自定义模块上传文件
        :return:布尔值，上传成功为True，上传失败为False
        """
        bool1 = ftp.push(sys.argv)
        if bool1:
            QMessageBox.information(self, "提示", "文件上传成功")
        else:
            QMessageBox.information(self, "提示", "文件上传失败")

    def next2(self):
        """
        改变查看索引值
        :return: None
        """
        global now_index
        if now_index < len(list_show_now) - 1:
            now_index += 1
        else:
            QMessageBox.information(self, "提示", "当前已经是最后一个结果！")
            now_index = 5

    def last2(self):
        """
        改变查看索引值
        :return: None
        """
        global now_index
        if now_index > 0:
            now_index -= 1
        else:
            QMessageBox.information(self, "提示", "当前已经是第一个结果！")

    def show_picture_now(self):
        """
        展示正在上映的电影的海报
        :return: None
        """
        headers = {
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                          'Chrome/83.0.4103.97 Safari/537.36 Edg/83.0.478.45 '
        }
        try:
            res = requests.get(list_show_now[now_index]['img'], headers=headers)
            root = "F://python全栈//python程序设计大实验//"
            path = root + '1.jpg'
            if not os.path.exists(root):
                os.mkdir(root)
            with open(path, 'wb') as f:
                f.write(res.content)
                f.close()
        except:
            QMessageBox.information(self, "提示", "海报资源请求错误")
        pix = QPixmap('1.jpg')
        picture_lab2 = QLabel(self)
        picture_lab2.setGeometry(950, 400, 600, 300)
        picture_lab2.setPixmap(pix)
        picture_lab2.setStyleSheet("border: 2px solid blue")
        picture_lab2.setScaledContents(True)
        picture_lab2.show()

    def openfile(self):
        """
        选择并打开文件，将爬取到的结果写入文件
        :return: None
        """
        global string
        filename = QFileDialog.getOpenFileName(self, '打开文件', './', "txt(*.txt)")
        if filename[0]:
            with open(filename[0], 'w', encoding="utf-8") as f:
                f.write(string)
        QMessageBox.information(self, "提示", "院线电影信息成功写入指定文件>_<")

    def readfile(self):
        """
        让用户选择并打开.txt文件并将其内容显示到文本栏中
        :return: None
        """
        filename = QFileDialog.getOpenFileName(self, '打开文件', './', "txt(*.txt)")
        if filename[0]:
            with open(filename[0], 'r', encoding='utf-8') as f:
                read_info = f.read()
        detail_text = QTextEdit(self)
        detail_text.setGeometry(950, 200, 600, 500)
        detail_text.setToolTip("这个文本框显示了读取到的文件的内容")
        detail_text.setReadOnly(False)
        detail_text.show()
        detail_text.setText(read_info)

    def closeEvent(self, event):
        """
        退出事件确认，更新状态栏状态
        :param event: 退出事件
        :return: None
        """
        self.statusBar().showMessage("退出确认！")
        reply = QMessageBox.question(self, "警告", "您确定要退出吗，未保存的修改将不被保存!",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
            self.statusBar().showMessage("准备就绪！")


def Win_build():
    """
    GUI构建主函数
    :return: None
    """
    app = QApplication(sys.argv)
    frame = Frame()
    frame.init_text()
    frame.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    Win_build()
